{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Intro - Perceptrons\n",
    "* Simplest ANN architecture\n",
    "* Uses *linear threshold unit (LTU)* - returns weight sum of inputs, applies *step function* to sum, outputs result\n",
    "* Single LTU can be used for simple linear binary classification\n",
    "* Perceptron = single layer of LTUs, each one connected to all inputs\n",
    "* Percepton training based on *Hebb's Rule*. (basically, connection weight between two neurons goes up when they have same output.)\n",
    "* Linear decision boundary, so Perceptrons not capable of learning complex patterns.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# Perceptron with Iris dataset (Scikit)\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "from sklearn.datasets import load_iris\n",
    "iris = load_iris()\n",
    "\n",
    "X = iris.data[:, (2, 3)]  # petal length, petal width\n",
    "y = (iris.target == 0).astype(np.int)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1]\n"
     ]
    }
   ],
   "source": [
    "from sklearn.linear_model import Perceptron\n",
    "\n",
    "per_clf = Perceptron(random_state=42)\n",
    "per_clf.fit(X, y)\n",
    "\n",
    "y_pred = per_clf.predict([[2, 0.5]])\n",
    "print(y_pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* Perceptron learning algo very similar go SGD.\n",
    "* Perceptrons do provide class probability (like Logistic Regression classsifier). They simply make predictions based on hard threshold.\n",
    "* Some limitations can be eliminated with stacked Perceptrons."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n/vprDyNH1uWHH+ZfZ2sR3/fCC6/i739lIXH77Xfw0UeL+Pnn77n//ur8+99P0qpVRwYNGuZcp0+f\nFwkMzEb9+hWpUKEg+/Zl3P1bISF52LhxHZ06NaNOnbK89toLPP/8K7Rtm/oAqPvue5DZs2fQvv2D\n1KtXnv/8pw916tTnk0+WOgdTDBgwhP79XycmJpoGDSrRrl0jFi78jLCwpClCAgICGDr0LWbOfI+q\nVYvSpUsLAJ56qh99+/Zn8OCXaNCgMosWzWXq1M+oXLmaI9/bmDlzCo88Up+IiMosXPgZ06bNoXjx\nkvj5+TF58sds2/YTERGVGTCgL//5zxCyZUv9nr+MZLLyzbx3313Grl8/ytNpiA/67bdJHD68FEgE\n/ChcuDFlyvRKcV13tbxKD29oYeWtFi7cSJcuozlz5rwz9sgjb9K06X8z5D4fyVruums7JUtW8HQa\nkoXt3r2d779P+WesVy+z2Vobfr196MybyFWSCrfFJBVuAIkcPryY336bdM267mp5lR7e1MLKGzVr\nVos1a0ZQqtTl6QgWLHiZKVMe4+LFcx7MTETkxqh4E7lK0hk31+LuanmVHt7YwsrbVKoUxrp1I4mI\nqOyMbdo0i+jo+pw4sd+DmYmIpJ+KN5FrJKYz7hp3tZry1hZW3iZ//hC+/PJ1evZs4ozt3buZ4cPD\n2b17gwczExFJHxVvItdI7dfi5n5d3NVqyptbWHmbwMAAxo/vxfjxPfH3T/p+njp1iFGjItiwQWcq\nRcQ3ZGrxZoxpYozZYYz5zRgzIIXlnYwxPxljthhjYo0x1ZIt2+OI/2CM2ZSZecutpXDhxi7H3dXy\nKj28vYWVN+rZsymLFr1Bvny5AUhIuMC0aY8zZ85/SEx03xxXIiIZIdOKN2OMPzABaApUBDoaY66e\n3GU3EGGtrQIMASZftfw+a211V0ZiiNyoMmV6UbhwEy7/evhRuHCTFEebuqvlVXr4Qgsrb9SwYRXW\nrRtBhQqXG28vXTqCiRNbcO7cKQ9mJiKStkybKsQYcw/wurX2QcfrgQDW2uGprJ8X+Nlae4fj9R4g\n3Frr8o08mipERK7n1KmzdOkymi+/vHxC//bbK9KnzwIKFiztwczEEzRViLibr00VcgfwZ7LX+xyx\n1HQDFiV7bYFlxpjNxpgebshPRG5BISE5+Oyzgbz4Yitn7ODBbURG1mLHjhUezExEJGVeOWDBGHMf\n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\nAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f0a0cbc1eb8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "a = -per_clf.coef_[0][0] / per_clf.coef_[0][1]\n",
    "b = -per_clf.intercept_ / per_clf.coef_[0][1]\n",
    "\n",
    "axes = [0, 5, 0, 2]\n",
    "\n",
    "x0, x1 = np.meshgrid(\n",
    "        np.linspace(axes[0], axes[1], 500).reshape(-1, 1),\n",
    "        np.linspace(axes[2], axes[3], 200).reshape(-1, 1),\n",
    "    )\n",
    "\n",
    "X_new = np.c_[\n",
    "    x0.ravel(), \n",
    "    x1.ravel()]\n",
    "\n",
    "y_predict = per_clf.predict(X_new)\n",
    "\n",
    "zz = y_predict.reshape(x0.shape)\n",
    "\n",
    "plt.figure(figsize=(10, 4))\n",
    "plt.plot(X[y==0, 0], X[y==0, 1], \"bs\", label=\"Not Iris-Setosa\")\n",
    "plt.plot(X[y==1, 0], X[y==1, 1], \"yo\", label=\"Iris-Setosa\")\n",
    "\n",
    "plt.plot(\n",
    "    [axes[0], \n",
    "     axes[1]], \n",
    "    [a * axes[0] + b, \n",
    "     a * axes[1] + b], \n",
    "    \"k-\", linewidth=3)\n",
    "\n",
    "from matplotlib.colors import ListedColormap\n",
    "custom_cmap = ListedColormap(['#9898ff', '#fafab0'])\n",
    "\n",
    "plt.contourf(x0, x1, zz, cmap=custom_cmap, linewidth=5)\n",
    "plt.xlabel(\"Petal length\", fontsize=14)\n",
    "plt.ylabel(\"Petal width\", fontsize=14)\n",
    "plt.legend(loc=\"lower right\", fontsize=14)\n",
    "plt.axis(axes)\n",
    "\n",
    "#save_fig(\"perceptron_iris_plot\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### MLPs and Backpropagation\n",
    "* MLP contains one input layer, at least one hidden layer (LTU based), and one output layer (LTU based).\n",
    "* Backpropagation intro'd in [1986 paper](https://goo.gl/Wl7Xyc). Can be described as Gradient Descent using reverse-mode autodiff.\n",
    "* For each training instance:\n",
    "    * Find output of each node in each consecutive layer (forward pass).\n",
    "    * Measure output error & how much each node in last hidden layer contributed to it.\n",
    "    * Measure how much each node in *previous* hidden layer contributed to *this* hidden layer.\n",
    "    * Repeat until *input* layer is reached (backward pass).\n",
    "    * Adjust each connection weight to reduce the error.\n",
    "* To make algorithm work, MLP architecture changed to use logistic function delta(z) = 1/(1+exp(-z)) instead of step function.\n",
    "* Backpropagation can also use hyperbolic tangent or ReLU functions if desired."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# Activation functions\n",
    "\n",
    "def logit(z):\n",
    "    return 1 / (1 + np.exp(-z))\n",
    "\n",
    "def relu(z):\n",
    "    return np.maximum(0, z)\n",
    "\n",
    "def derivative(f, z, eps=0.000001):\n",
    "    return (f(z + eps) - f(z - eps))/(2 * eps)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f0a068ae198>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "z = np.linspace(-5, 5, 200)\n",
    "\n",
    "plt.figure(figsize=(11,4))\n",
    "\n",
    "plt.subplot(121)\n",
    "plt.plot(z, np.sign(z), \"r-\", linewidth=2, label=\"Step\")\n",
    "plt.plot(z, logit(z), \"g--\", linewidth=2, label=\"Logit\")\n",
    "plt.plot(z, np.tanh(z), \"b-\", linewidth=2, label=\"Tanh\")\n",
    "plt.plot(z, relu(z), \"m-.\", linewidth=2, label=\"ReLU\")\n",
    "plt.grid(True)\n",
    "plt.legend(loc=\"center right\", fontsize=14)\n",
    "plt.title(\"Activation functions\", fontsize=14)\n",
    "plt.axis([-5, 5, -1.2, 1.2])\n",
    "\n",
    "plt.subplot(122)\n",
    "plt.plot(z, derivative(np.sign, z), \"r-\", linewidth=2, label=\"Step\")\n",
    "plt.plot(0, 0, \"ro\", markersize=5)\n",
    "plt.plot(0, 0, \"rx\", markersize=10)\n",
    "plt.plot(z, derivative(logit, z), \"g--\", linewidth=2, label=\"Logit\")\n",
    "plt.plot(z, derivative(np.tanh, z), \"b-\", linewidth=2, label=\"Tanh\")\n",
    "plt.plot(z, derivative(relu, z), \"m-.\", linewidth=2, label=\"ReLU\")\n",
    "plt.grid(True)\n",
    "#plt.legend(loc=\"center right\", fontsize=14)\n",
    "plt.title(\"Derivatives\", fontsize=14)\n",
    "plt.axis([-5, 5, -0.2, 1.2])\n",
    "\n",
    "#save_fig(\"activation_functions_plot\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# activation functions, continued\n",
    "def heaviside(z):\n",
    "    return (z >= 0).astype(z.dtype)\n",
    "\n",
    "def sigmoid(z):\n",
    "    return 1/(1+np.exp(-z))\n",
    "\n",
    "def mlp_xor(x1, x2, activation=heaviside):\n",
    "    return activation(\n",
    "        -activation(x1 + x2 - 1.5) + activation(x1 + x2 - 0.5) - 0.5)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f0a06884e80>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x1s = np.linspace(-0.2, 1.2, 100)\n",
    "x2s = np.linspace(-0.2, 1.2, 100)\n",
    "x1, x2 = np.meshgrid(x1s, x2s)\n",
    "\n",
    "z1 = mlp_xor(x1, x2, activation=heaviside)\n",
    "z2 = mlp_xor(x1, x2, activation=sigmoid)\n",
    "\n",
    "plt.figure(figsize=(10,4))\n",
    "\n",
    "plt.subplot(121)\n",
    "plt.contourf(x1, x2, z1)\n",
    "plt.plot([0, 1], [0, 1], \"gs\", markersize=20)\n",
    "plt.plot([0, 1], [1, 0], \"y^\", markersize=20)\n",
    "plt.title(\"Activation function: heaviside\", fontsize=14)\n",
    "plt.grid(True)\n",
    "\n",
    "plt.subplot(122)\n",
    "plt.contourf(x1, x2, z2)\n",
    "plt.plot([0, 1], [0, 1], \"gs\", markersize=20)\n",
    "plt.plot([0, 1], [1, 0], \"y^\", markersize=20)\n",
    "plt.title(\"Activation function: sigmoid\", fontsize=14)\n",
    "plt.grid(True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### MLP Training\n",
    "* MLP often used for classification - each output corresponding to distinct binary class (ex: urgent/not-urgent, spam/not-spam, ...)\n",
    "* If exclusive classes, output layer often uses shared **softmax** function."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DNN Training with \"plain\" TF\n",
    "* Use **mini-batch gradient descent** on MNIST dataset\n",
    "* Specify #inputs, #outputs, #hidden neurons in each layer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "\n",
    "tf.reset_default_graph()\n",
    "\n",
    "n_inputs = 28*28  # MNIST\n",
    "n_hidden1 = 300\n",
    "n_hidden2 = 100\n",
    "n_outputs = 10\n",
    "learning_rate = 0.01\n",
    "\n",
    "# placeholders for training data & targets\n",
    "# X,y only partially defined due to unknown #instances in training batches\n",
    "\n",
    "X = tf.placeholder(tf.float32, shape=(None, n_inputs), name=\"X\")\n",
    "y = tf.placeholder(tf.int64,   shape=(None),           name=\"y\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# now need to create two hidden layers + one output layer\n",
    "\n",
    "'''\n",
    "No need to define your own. TF shortcuts:\n",
    "fully_connected()\n",
    "'''\n",
    "\n",
    "def neuron_layer(X, n_neurons, name, activation=None):\n",
    "    \n",
    "    # define a name scope to aid readability\n",
    "    with tf.name_scope(name):\n",
    "        \n",
    "        n_inputs = int(X.get_shape()[1])\n",
    "        \n",
    "        # create weights matrix. 2D (#inputs, #neurons)\n",
    "        # randomly initialized w/ truncated Gaussian, stdev = 2/sqrt(#inputs)\n",
    "        # aids convergence speed\n",
    "        \n",
    "        stddev = 1 / np.sqrt(n_inputs)\n",
    "        init = tf.truncated_normal((n_inputs, n_neurons), stddev=stddev)       \n",
    "        W = tf.Variable(init, name=\"weights\")\n",
    "        \n",
    "        # create bias variable, initialized to zero, one param per neuron\n",
    "        b = tf.Variable(tf.zeros([n_neurons]), name=\"biases\")\n",
    "        \n",
    "        # Z = X dot W + b\n",
    "        Z = tf.matmul(X, W) + b\n",
    "        \n",
    "        # return relu(z), or simply z\n",
    "        if activation==\"relu\":\n",
    "            return tf.nn.relu(Z)\n",
    "        else:\n",
    "            return Z"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "with tf.name_scope(\"dnn\"):\n",
    "    hidden1 = neuron_layer(X,       n_hidden1, \"hidden1\", activation=\"relu\")\n",
    "    hidden2 = neuron_layer(hidden1, n_hidden2, \"hidden2\", activation=\"relu\")\n",
    "    \n",
    "    # logits = NN output before going thru softmax activation\n",
    "    logits =  neuron_layer(hidden2, n_outputs, \"output\")\n",
    "\n",
    "with tf.name_scope(\"loss\"):\n",
    "    \n",
    "    # sparse_softmax_cross_entropy_with_logits() -- TF routine, handles corner cases for you.\n",
    "    xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(\n",
    "        labels=y, \n",
    "        logits=logits)\n",
    "    \n",
    "    # use reduce_mean() to find mean cross-entropy over all instances.\n",
    "    loss = tf.reduce_mean(\n",
    "        xentropy, \n",
    "        name=\"loss\")\n",
    "\n",
    "# use GD to handle cost function, ie minimize loss\n",
    "with tf.name_scope(\"train\"):\n",
    "    optimizer = tf.train.GradientDescentOptimizer(learning_rate)\n",
    "    training_op = optimizer.minimize(loss)\n",
    "\n",
    "# use accuracy as performance measure.\n",
    "\n",
    "with tf.name_scope(\"eval\"):        # verify whether highest logit corresponds to target class\n",
    "    correct = tf.nn.in_top_k(      # using in_top_k(), returns 1D tensor of booleans\n",
    "        logits, y, 1)\n",
    "    \n",
    "    accuracy = tf.reduce_mean(             # recast booleans to float & find avg.\n",
    "        tf.cast(correct, tf.float32))      # this gives overall accuracy number.\n",
    "\n",
    "init = tf.global_variables_initializer()   # initializer node\n",
    "saver = tf.train.Saver()                   # to save trained params to disk"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Execution Phase\n",
    "* Load MNIST using TF helpers (fetch, auto-scale, shuffle, provide minibatch function)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting /tmp/data/train-images-idx3-ubyte.gz\n",
      "Extracting /tmp/data/train-labels-idx1-ubyte.gz\n",
      "Extracting /tmp/data/t10k-images-idx3-ubyte.gz\n",
      "Extracting /tmp/data/t10k-labels-idx1-ubyte.gz\n"
     ]
    }
   ],
   "source": [
    "# load MNIST\n",
    "\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "mnist = input_data.read_data_sets(\"/tmp/data/\")\n",
    "\n",
    "n_epochs = 20\n",
    "batch_size = 50"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 Train accuracy: 0.94 Test accuracy: 0.8753\n",
      "1 Train accuracy: 0.9 Test accuracy: 0.9087\n",
      "2 Train accuracy: 0.94 Test accuracy: 0.9212\n",
      "3 Train accuracy: 0.88 Test accuracy: 0.9239\n",
      "4 Train accuracy: 0.88 Test accuracy: 0.9335\n",
      "5 Train accuracy: 0.96 Test accuracy: 0.9365\n",
      "6 Train accuracy: 0.92 Test accuracy: 0.9415\n",
      "7 Train accuracy: 0.94 Test accuracy: 0.9449\n",
      "8 Train accuracy: 0.96 Test accuracy: 0.9459\n",
      "9 Train accuracy: 0.94 Test accuracy: 0.9497\n",
      "10 Train accuracy: 1.0 Test accuracy: 0.9539\n",
      "11 Train accuracy: 0.94 Test accuracy: 0.9563\n",
      "12 Train accuracy: 0.98 Test accuracy: 0.958\n",
      "13 Train accuracy: 0.98 Test accuracy: 0.9584\n",
      "14 Train accuracy: 0.94 Test accuracy: 0.9614\n",
      "15 Train accuracy: 1.0 Test accuracy: 0.9622\n",
      "16 Train accuracy: 0.96 Test accuracy: 0.9639\n",
      "17 Train accuracy: 0.92 Test accuracy: 0.9635\n",
      "18 Train accuracy: 0.98 Test accuracy: 0.9654\n",
      "19 Train accuracy: 0.92 Test accuracy: 0.9667\n"
     ]
    }
   ],
   "source": [
    "# Train\n",
    "with tf.Session() as sess:\n",
    "\n",
    "    init.run() # initialize all variables\n",
    "    \n",
    "    for epoch in range(n_epochs):\n",
    "        for iteration in range(mnist.train.num_examples // batch_size):\n",
    "\n",
    "            # use next_batch() to fetch data\n",
    "            X_batch, y_batch = mnist.train.next_batch(batch_size)\n",
    "\n",
    "            sess.run(\n",
    "                training_op, \n",
    "                feed_dict={X: X_batch, y: y_batch})\n",
    "\n",
    "        acc_train = accuracy.eval(\n",
    "            feed_dict={X: X_batch, y: y_batch})\n",
    "\n",
    "        acc_test = accuracy.eval(\n",
    "            feed_dict={X: mnist.test.images,\n",
    "                       y: mnist.test.labels})\n",
    "\n",
    "        print(epoch, \"Train accuracy:\", acc_train, \"Test accuracy:\", acc_test)\n",
    "\n",
    "        save_path = saver.save(sess, \"./my_model_final.ckpt\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### Using in production\n",
    "* Now trained - you can use the NN to predict."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[7 2 1 0 4 1 4 9 6 9 0 6 9 0 1 5 9 7 3 4]\n",
      "[7 2 1 0 4 1 4 9 5 9 0 6 9 0 1 5 9 7 3 4]\n"
     ]
    }
   ],
   "source": [
    "with tf.Session() as sess:\n",
    "\n",
    "    # load from disk\n",
    "    saver.restore(sess, save_path) #\"my_model_final.ckpt\")\n",
    "    \n",
    "    # grab images you want to classify\n",
    "    X_new_scaled = mnist.test.images[:20]\n",
    "    \n",
    "    Z = logits.eval(feed_dict={X: X_new_scaled})\n",
    "    print(np.argmax(Z, axis=1))\n",
    "    print(mnist.test.labels[:20])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Parameter Tuning\n",
    "* Way too many parameters - Grid Search approach not time-effective.\n",
    "* 1st option: [randomized search](https://goo.gl/QFjMKu).\n",
    "* 2nd option: [Oscar](http://oscar.calldesk.ai/)\n",
    "* Start with common defaults to restrict search space."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### Number of hidden layers\n",
    "* Deep nets have **much better parameter efficiency** than shallow ones. (They can model complex functions with much fewer neurons.)\n",
    "* Largely due to hierarchical nature of most data modeling probs\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### Number of neurons per hidden layer\n",
    "* Determined by input dimensions. Ex: MNIST requires 28x28 inputs, 10 outputs\n",
    "* Try increasing # of layers before # neurons/layer.\n",
    "* Simple trick: pick model w/ excessive layers & neurons, use early stopping, regularization, dropout, etc. to prevent overfit."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "### Activation functions\n",
    "* Defaults:\n",
    "    * use ReLU in hidden layers. Faster & helps avoid GD getting stuck on local plateaus.\n",
    "    * use Softmax in output layer (for classification; none needed for regression.) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [Root]",
   "language": "python",
   "name": "Python [Root]"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
